<script setup lang="ts">
import type { DeptOption } from '#/api/system/role/model';

import { ref, nextTick, watch } from 'vue';

import { useVbenModal } from '@vben/common-ui';
import { cloneDeep } from '@vben/utils';
import { message } from 'ant-design-vue';

import { useVbenForm } from '#/adapter/form';
import { roleDataScope, roleDeptTree, roleInfo, getRoleDataScopeConfig, updateRoleDataScopeConfig, deleteRoleDataScopeConfig } from '#/api/system/role';
import { TreeSelectPanel } from '#/components/tree';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';

import { authModalSchemas } from './data';
import DataScopeConfig from './components/DataScopeConfig.vue';

const emit = defineEmits<{ reload: [] }>();

const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    componentProps: {
      class: 'w-full',
    },
  },
  layout: 'vertical',
  schema: authModalSchemas(),
  showDefaultActions: false,
});

// 不需要注册自定义组件，将通过slot方式使用

const deptTree = ref<DeptOption[]>([]);
const dataScopeConfigRef = ref<InstanceType<typeof DataScopeConfig>>();
const currentRoleId = ref<number | string>();

async function setupDeptTree(id: number | string) {
  const resp = await roleDeptTree(id);
  formApi.setFieldValue('deptIds', resp.checkedKeys);
  // 设置菜单信息
  deptTree.value = resp.depts;
}

// 加载数据权限配置
async function setupDataScopeConfig(id: number | string) {
  try {
    console.log('开始加载角色数据权限配置，角色ID:', id);
    const resp: any = await getRoleDataScopeConfig(id);
    console.log('数据权限配置API响应:', resp);
    
    // 根据API响应结构处理数据
    let configs: any[] = [];
    if (Array.isArray(resp)) {
      configs = resp;
    } else if (resp && resp.data) {
      configs = resp.data;
    } else if (resp && Array.isArray(resp.rows)) {
      configs = resp.rows;
    }
    
    console.log('处理后的配置数据:', configs);
    formApi.setFieldValue('dataScopeConfigs', configs);
    console.log('已设置配置数据到表单, 数量:', configs.length);
    
    // 强制触发表单更新
    await nextTick();
    
  } catch (error: any) {
    console.error('加载数据权限配置失败:', error);
    // 如果加载失败，设置为空数组
    formApi.setFieldValue('dataScopeConfigs', []);
  }
}

async function customFormValueGetter() {
  const v = await defaultFormValueGetter(formApi)();
  // 获取勾选信息
  const menuIds = deptSelectRef.value?.[0]?.getCheckedKeys() ?? [];
  const mixStr = v + menuIds.join(',');
  return mixStr;
}

const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
  {
    initializedGetter: customFormValueGetter,
    currentGetter: customFormValueGetter,
  },
);

const [BasicModal, modalApi] = useVbenModal({
  fullscreenButton: false,
  // width: 1600, // 进一步增加弹窗宽度至1600px，确保所有列都能完全显示 - 暂时注释解决类型错误  
  // bodyStyle: { maxHeight: '80vh', overflow: 'auto', padding: '20px' }, // 增加内容区域高度和内边距 - 暂时注释解决类型错误
  onBeforeClose,
  onClosed: handleClosed,
  onConfirm: handleConfirm,
  onOpenChange: async (isOpen) => {
    if (!isOpen) {
      return null;
    }
    modalApi.modalLoading(true);

    const { id } = modalApi.getData() as { id: number | string };
    currentRoleId.value = id;

    setupDeptTree(id);
    
    // 先获取角色信息
    const record = await roleInfo(id);
    console.log('==== 加载角色信息 ====');
    console.log('角色ID:', id);
    console.log('角色信息:', record);
    console.log('enableAdvancedFieldPermission字段值:', record.enableAdvancedFieldPermission);
    
    // 先设置角色信息到表单
    await formApi.setValues(record);
    
    // 根据角色的高级权限开关状态决定是否加载数据权限配置
    if (record.enableAdvancedFieldPermission === '1') {
      console.log('角色已启用高级权限，开始加载数据权限配置...');
      await setupDataScopeConfig(id);
    } else {
      console.log('角色未启用高级权限，跳过数据权限配置加载');
      // 确保配置数据为空
      formApi.setFieldValue('dataScopeConfigs', []);
    }
    
    markInitialized();

    modalApi.modalLoading(false);
  },
});

/**
 * 这里拿到的是一个数组ref
 */
const deptSelectRef = ref();

async function handleConfirm() {
  try {
    modalApi.lock(true);
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    
    // formApi.getValues拿到的是一个readonly对象，不能直接修改，需要cloneDeep
    const data = cloneDeep(await formApi.getValues());
    
    // 如果启用了高级字段权限，检查数据权限配置的验证状态
    if (data.enableAdvancedFieldPermission === '1') {
      console.log('==== 开始验证高级字段权限配置 ====');
      console.log('formApi获取的原始数据:', JSON.stringify(data, null, 2));
      console.log('data.dataScopeConfigs:', data.dataScopeConfigs);
      console.log('dataScopeConfigRef.value存在:', !!dataScopeConfigRef.value);
      
      // 无论如何都尝试从子组件获取最新数据，确保数据同步
      if (dataScopeConfigRef.value && dataScopeConfigRef.value.debugFormState) {
        console.log('尝试从子组件获取最新数据...');
        const debugInfo = dataScopeConfigRef.value.debugFormState();
        console.log('子组件调试信息:', JSON.stringify(debugInfo, null, 2));
        
        // 如果子组件有数据，则使用子组件的数据（这是最准确的）
        if (debugInfo.configs && debugInfo.configs.length > 0) {
          console.log('使用子组件的配置数据，数量:', debugInfo.configs.length);
          data.dataScopeConfigs = [...debugInfo.configs]; // 创建副本避免引用问题
          console.log('从子组件获取的配置数据:', JSON.stringify(data.dataScopeConfigs, null, 2));
          
          // 同步更新表单字段值
          await formApi.setFieldValue('dataScopeConfigs', data.dataScopeConfigs);
          console.log('已更新表单字段值');
        } else if (!data.dataScopeConfigs || data.dataScopeConfigs.length === 0) {
          console.log('子组件和formApi都没有配置数据');
        }
      }
      
      console.log('最终用于提交的dataScopeConfigs:', JSON.stringify(data.dataScopeConfigs, null, 2));
      console.log('配置数量:', data.dataScopeConfigs ? data.dataScopeConfigs.length : 0);
      
      // 检查组件引用是否存在
      if (!dataScopeConfigRef.value) {
        console.log('dataScopeConfigRef.value 不存在');
        message.warning('权限配置组件未正确加载，请刷新页面重试');
        return;
      }
      
      // 调用调试函数获取详细状态
      if (dataScopeConfigRef.value.debugFormState) {
        const debugInfo = dataScopeConfigRef.value.debugFormState();
        console.log('权限配置组件调试信息:', debugInfo);
      }
      
      // 检查是否至少有一个配置项
      if (!data.dataScopeConfigs || data.dataScopeConfigs.length === 0) {
        console.log('没有权限配置项');
        message.warning('启用高级字段权限后，请至少添加一个权限配置');
        return;
      }
      
      // 验证每个配置项是否完整
      const hasErrors = dataScopeConfigRef.value.hasValidationErrors();
      console.log('组件验证结果:', hasErrors);
      
      if (hasErrors) {
        message.warning('请完善字段权限配置，确保所有必填项都已填写');
        return;
      }
      
      // 额外检查：确保所有配置项都有必要的字段
      const incompleteConfig = data.dataScopeConfigs.find((config: any) => 
        !config.menuId || 
        !config.permission || 
        !config.filterField || 
        !config.filterValues?.trim()
      );
      
      if (incompleteConfig) {
        console.log('发现不完整的配置项:', incompleteConfig);
        message.warning('存在不完整的权限配置项，请检查所有必填字段');
        return;
      }
      
      console.log('==== 高级字段权限配置验证通过 ====');
    }
    
    // 处理部门权限
    if (data.dataScope === '2') {
      const deptIds = deptSelectRef.value?.[0]?.getCheckedKeys() ?? [];
      data.deptIds = deptIds;
    } else {
      data.deptIds = [];
    }
    
    // 高级字段权限是在原有数据范围基础上的进一步细分
    // 不修改原有的dataScope值，保持用户选择的原有数据范围（1-6）
    // enable_advanced_field_permission 字段由开关状态决定
    
    // 先更新角色数据权限范围
    console.log('==== 准备更新角色数据权限 ====');
    console.log('提交的角色数据:', data);
    console.log('enableAdvancedFieldPermission值:', data.enableAdvancedFieldPermission);
    
    await roleDataScope(data);
    console.log('角色数据权限更新完成');
    
    // 处理高级字段权限配置
    console.log('==== 开始处理高级字段权限配置 ====');
    if (data.enableAdvancedFieldPermission === '1') {
      console.log('高级字段权限已启用');
      // 如果启用了高级字段权限且有配置数据，则更新配置
      if (data.dataScopeConfigs && data.dataScopeConfigs.length > 0) {
        console.log(`开始更新高级字段权限配置，共${data.dataScopeConfigs.length}条`);
        const configs = data.dataScopeConfigs.map((config: any, index: number) => {
          const configWithRoleId = {
            ...config,
            roleId: data.roleId,
          };
          console.log(`配置[${index}]:`, JSON.stringify(configWithRoleId, null, 2));
          return configWithRoleId;
        });
        
        console.log('即将提交到后端的配置数据:', JSON.stringify(configs, null, 2));
        
        try {
          const result = await updateRoleDataScopeConfig(configs);
          console.log('后端API调用成功，返回结果:', result);
          console.log('高级字段权限配置更新完成');
          message.success(`成功保存${configs.length}条权限配置`);
        } catch (error: any) {
          console.error('更新高级字段权限配置失败:', error);
          message.error('保存权限配置失败：' + (error?.message || '未知错误'));
          throw error; // 重新抛出错误以阻断流程
        }
      } else {
        console.log('启用了高级字段权限但无配置数据');
        message.warning('启用了高级字段权限但没有配置数据');
      }
    } else {
      console.log('高级字段权限已关闭');
      // 如果关闭了高级字段权限，需要删除该角色的所有配置数据
      console.log('高级字段权限已关闭，开始删除该角色的所有配置数据');
      try {
        const result = await deleteRoleDataScopeConfig(data.roleId);
        console.log('删除配置API调用成功，返回结果:', result);
        console.log('角色配置数据删除完成');
        message.success('已清空所有权限配置');
      } catch (error: any) {
        console.error('删除角色配置数据失败:', error);
        message.error('删除权限配置失败：' + (error?.message || '未知错误'));
        // 不阻断主流程，只记录错误
      }
    }
    console.log('==== 高级字段权限配置处理完成 ====');
    
    resetInitialized();
    emit('reload');
    modalApi.close();
  } catch (error) {
    console.error(error);
  } finally {
    modalApi.lock(false);
  }
}

async function handleClosed() {
  await formApi.resetForm();
  resetInitialized();
  currentRoleId.value = undefined; // 清理角色ID
}

/**
 * 通过回调更新 无法通过v-model
 * @param value 菜单选择是否严格模式
 */
function handleCheckStrictlyChange(value: boolean) {
  formApi.setFieldValue('deptCheckStrictly', value);
}

// 监听高级权限开关变化 - 实现动态加载配置功能
watch(
  () => {
    try {
      // 确保表单已初始化且有值时才返回
      if (formApi?.form?.values && typeof formApi.form.values.enableAdvancedFieldPermission !== 'undefined') {
        return formApi.form.values.enableAdvancedFieldPermission;
      }
      return null;
    } catch (error) {
      console.warn('表单数据访问失败:', error);
      return null;
    }
  },
  async (newValue, oldValue) => {
    // 安全检查：确保组件已初始化且值确实发生了变化
    if (!newValue || !currentRoleId.value || newValue === oldValue) {
      return;
    }
    
    console.log('==== 高级权限开关状态变化 ====');
    console.log('旧值:', oldValue, '新值:', newValue, '角色ID:', currentRoleId.value);
    
    try {
      if (newValue === '1') {
        // 开关打开时，动态加载配置数据
        console.log('开关已打开，动态加载配置数据...');
        await setupDataScopeConfig(currentRoleId.value);
      } else if (newValue === '0') {
        // 开关关闭时，清空配置数据
        console.log('开关已关闭，清空配置数据...');
        formApi.setFieldValue('dataScopeConfigs', []);
        // 注意：这里只是前端清空显示，真正的删除在表单提交时进行
      }
    } catch (error) {
      console.error('处理开关状态变化时出错:', error);
    }
  },
  { 
    immediate: false, 
    flush: 'post' // 确保在DOM更新后执行
  }
);
</script>

<template>
  <BasicModal 
    class="min-h-[600px]" 
    title="分配权限"
    :style="{ width: '1600px', maxHeight: '80vh', overflow: 'auto' }"
  >
    <div style="padding: 20px;">
      <BasicForm>
      <template #deptIds="slotProps">
        <TreeSelectPanel
          ref="deptSelectRef"
          v-bind="slotProps"
          :check-strictly="formApi.form.values.deptCheckStrictly"
          :expand-all-on-init="true"
          :tree-data="deptTree"
          @check-strictly-change="handleCheckStrictlyChange"
        />
      </template>
      
      <template #dataScopeConfigs="slotProps">
        <DataScopeConfig 
          ref="dataScopeConfigRef"
          :value="slotProps.value" 
          @update:value="(value) => {
            console.log('==== DataScopeConfig 数据更新 ====');
            console.log('接收到的新数据:', value);
            console.log('slotProps.onChange 检查:', typeof slotProps.onChange, slotProps.onChange);
            
            // 安全地调用 onChange，防止函数不存在的错误
            if (slotProps && typeof slotProps.onChange === 'function') {
              try {
                slotProps.onChange(value);
                console.log('slotProps.onChange 调用成功');
              } catch (error) {
                console.error('slotProps.onChange 调用失败:', error);
              }
            } else {
              console.warn('slotProps.onChange 不是有效函数，跳过调用');
            }
            
            // 强制触发表单字段更新
            nextTick(() => {
              try {
                formApi.setFieldValue('dataScopeConfigs', value);
                console.log('强制更新表单字段完成');
              } catch (error) {
                console.error('更新表单字段失败:', error);
              }
            });
          }" 
        />
      </template>
    </BasicForm>
    </div>
  </BasicModal>
</template>
